-- ======================================================================
-- Hell Logic Sniffer Addon 
-- 
-- Copyright 2013 Hell-Prototypes
--
-- http://www.hellprototypes.com/
-- ======================================================================

ModuleClass = "LS_PLUGIN"
ModuleName  = "I2C Analyse"
ModuleTip   = "Analyse I2C bus decoded data"

g_channel_number_from_input = false

g_all_device_data = {}

function get_current_channel()
	local param = LS_API.GetCommonParameter()
	if #param < 4 then
		LS_API.MessageBox("<I2C Analyse> Error param : table size : " .. #param)
		return -1
	end

	return param[4]
end

function input_channel_number()
	local channel = LS_API.InputBox(0, "Input channel num(0~15):")
    if channel == nil or channel >= 16 or channel < 0 then
        return -1;
    end

	return channel
end

function main ()
    local current_channel = get_current_channel()
    if current_channel < 0 then
		current_channel = input_channel_number()
		if current_channel < 0 then
			LS_API.MessageBox("Error channel num: " .. channel .. ", End Work.")
			return
		end
		g_channel_number_from_input = true
    end

    local Decoded_Data = LS_API.GetChannelDecodedData(current_channel)
    
    if type(Decoded_Data) ~= "table" then
		if g_channel_number_from_input == false then
			current_channel = input_channel_number()
			if current_channel < 0 then
				LS_API.MessageBox("Error channel num: " .. current_channel .. ", End Work.")
				return
			end
			Decoded_Data = LS_API.GetChannelDecodedData(current_channel)
			if type(Decoded_Data) ~= "table" then
				LS_API.MessageBox("No decoded data found in channel : " .. current_channel)
				return
			end
		else
			LS_API.MessageBox("No decoded data found in channel : " .. current_channel)
			return
		end
		return
	end

    LS_API.ReportPushBack("========================================================")
    LS_API.ReportPushBack("I2C bus data analyse, Decode data length : " .. #Decoded_Data/2)
	LS_API.ReportPushBack("========================================================\r\n")

    local index = 1
	local element = ""
	local state = "start"
	local address = ""
    while index < #Decoded_Data do
        --LS_API.ReportPushBack( (index/2 + 0.5) .. ": " .. Decoded_Data[index] .. "\t = \t" .. Decoded_Data[index+1])
		local decode = Decoded_Data[index+1]
		if state == "start" then
			if decode == "ST" then
				--element = element .. decode .. " "
				state = "addr"
			end
		elseif state == "addr" then
			element = element .. decode .. " "
			address = decode
			state = "stop"
		elseif state == "stop" then
			if decode == "SP" then
				local matching = false
				for i=1,#g_all_device_data do
					if g_all_device_data[i].address == address then
						matching = true
						g_all_device_data[i].comm_data[#g_all_device_data[i].comm_data + 1] = element
					end
				end
				if matching == false then
					local device_data = {
						address = "",
						comm_data = {},
					}
					device_data.address = address
					device_data.comm_data[1] = element
					LS_API.DebugMsg("device_data.comm_data[1] : " .. device_data.comm_data[1])
					g_all_device_data[#g_all_device_data + 1] = device_data
				end
				element = ""
				state = "start"
			else
				element = element .. decode .. " "
			end
		end
        index = index + 2
    end

	if #g_all_device_data > 0 then
		LS_API.ReportPushBack("# " .. #g_all_device_data .. " I2C device found")
		for i=1,#g_all_device_data do
			LS_API.ReportPushBack("Device " .. i .. " : Address = " .. g_all_device_data[i].address .. " , Number of Communication = " .. #g_all_device_data[i].comm_data)
			for j=1, #g_all_device_data[i].comm_data do
				LS_API.ReportPushBack("    " .. g_all_device_data[i].comm_data[j] )
			end
			LS_API.ReportPushBack("\r\n========================================\r\n")
		end
	else
		LS_API.ReportPushBack("# No I2C data found in the decode data ...")
	end
end